package com.zhangdi.dwcache.redis.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.DefaultLettucePool;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
    private String hostname = "127.0.0.1";
    private int port = 6379;
    private int minIdle = 2;
    private int maxIdle = 2;
    private int maxTotal = 5;

    public RedisConfig() {
    }

    public RedisConfig(String hostname, int port) {
        this.hostname = hostname;
        this.port = port;
    }

    @Bean(name = "mRedisTemplate")
    public <K, V> RedisTemplate<K,V> mRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory){
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);

        RedisSerializer<String> keySerializer = new StringRedisSerializer();
        RedisTemplate<K, V> redisTemplate = new RedisTemplate<K, V>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);

        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setHashKeySerializer(keySerializer);

        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashValueSerializer(serializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public  LettuceConnectionFactory lettuceConnectionFactory(DefaultLettucePool defaultLettucePool){
        return new LettuceConnectionFactory(defaultLettucePool);
    }

    @Bean
    DefaultLettucePool defaultLettucePool(GenericObjectPoolConfig poolConfig){
        DefaultLettucePool pool = new DefaultLettucePool();
        pool.setHostName(hostname);
        pool.setPort(port);
        pool.setPoolConfig(poolConfig);
        return pool;
    }

    @Bean
    GenericObjectPoolConfig poolConfig(){
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxIdle(maxIdle);
        config.setMinIdle(minIdle);
        config.setMaxTotal(maxTotal);
        return config;
    }
}
